/**
 * Created by root on 19-10-21.
 * 绘制纹理
 */

#ifndef OPENGLESPRO_GAME_STEP_6_H
#define OPENGLESPRO_GAME_STEP_6_H

#include <cstring>

#define VERTEX_ATTR_INDEX_V6_POSITION 1
#define VERTEX_ATTR_INDEX_V6_TEXTURE 2
#define VERTEX_VEC_COUNT_V6_PER_POSITION 2
#define VERTEX_VEC_COUNT_V6_PER_TEXTURE 2
#define ARRAY_VEC_COUNT_V6_TOTAL 16
#define STRIDE_BYTES_V6 sizeof(GLfloat)*(VERTEX_VEC_COUNT_V6_PER_POSITION+VERTEX_VEC_COUNT_V6_PER_TEXTURE)

void setUniform(GLuint program, int w = device.width, int h = device.height) {
    float transformMatrix[] = {
            1, 0, 0, 0,
            0, 1, 0, 0,
            0, 0, 1, -2.5,
            0, 0, 0, 1
    };//原本是沿着z轴平移-2个单位，但考虑到旋转，会导致距视椎体近平面的部分被截断，故而平移增至-2.5个单位
    glUniformMatrix4fv(glGetUniformLocation(program, "traMatrix"), 1, GL_FALSE,
                       transformMatrix);//由于下面的视椎体z分量范围是-1～~10，所以这里将所有顶点坐标沿着z轴平移至-2，保证处于视椎体范围内

    glUniform1f(glGetUniformLocation(program, "aspect"),
                w > h ? (float) h / (float) w : (float) w / (float) h);
    glUniform1f(glGetUniformLocation(program, "far"), 10);
    glUniform1f(glGetUniformLocation(program, "near"), 1);
    glUniform1f(glGetUniformLocation(program, "scanRad"), (float) (PI / 2));//90度
}

GLuint texId;
GLuint program;
AndroidBitmapInfo bitmapInfo = {};
AndroidBitmapInfo *bitmapInfoPtr = &bitmapInfo;

void OnSurfaceCreatedV6();

void OnSurfaceCreatedV6() {
    JNIEnv *env = device.jniEnv;
    jobject bitmap = device.bitmap;
    LOGI("sizeof bitmapInfo is %d, sizeof bitmapInfoPtr is %d, sizeof AndroidBitmapInfo is %d",
         sizeof(bitmapInfo), sizeof(bitmapInfoPtr), sizeof(AndroidBitmapInfo));
    texId = glesLoadSingleTexture2D(env, bitmap, bitmapInfoPtr);
    char vertexBuffer[GLSL_BUFFER_SIZE] = {};
    char fragmentBuffer[GLSL_BUFFER_SIZE] = {};
    glesGetTextForAsset(env, device.assetManager, "game/vertex_game_step_6_2.glsl", vertexBuffer);
    glesGetTextForAsset(env, device.assetManager, "game/fragment_game_step_6_2.glsl",
                        fragmentBuffer);
    program = glesInitialize(vertexBuffer, fragmentBuffer);
}

void OnSurfaceChangedV6();

int realWidth, realHeight;
GLfloat originalPointers[ARRAY_VEC_COUNT_V6_TOTAL];

void OnSurfaceChangedV6() {
    if (!bitmapInfoPtr)return;
    int w = device.width;
    int h = device.height;
    if (w < h) { // 竖屏
        realWidth = bitmapInfo.width > w ? w : bitmapInfo.width;
        realHeight = realWidth / bitmapInfo.width * bitmapInfo.height;
    } else {
        realHeight = bitmapInfo.height > h ? h : bitmapInfo.height;
        realWidth = realHeight / bitmapInfo.height * bitmapInfo.width;
    }
    GLfloat data[ARRAY_VEC_COUNT_V6_TOTAL] = {
            -realWidth / (float) w, -realHeight / (float) h, 0, 1,
            realWidth / (float) w, -realHeight / (float) h, 1, 1,
            -realWidth / (float) w, realHeight / (float) h, 0, 0,
            realWidth / (float) w, realHeight / (float) h, 1, 0
    };
    memcpy(originalPointers, data, ARRAY_VEC_COUNT_V6_TOTAL * sizeof(GLfloat));
    LOGI("bitmap real width:%d, bitmap real height:%d", realWidth, realHeight);
}

void OnDrawFrameV6();

void OnDrawFrameV6() {
    GLfloat vertexPointers[] = {
            // Order of coordinates: X, Y, S, T

            // Triangle Fan
            -0.5, -0.8, 0, 1,
            0.5, -0.8, 1, 1,
            0.5, 0.8, 1, 0,
            -0.5, 0.8, 0, 0
    };
    glUseProgram(device.program);
    glBindTexture(GL_TEXTURE_2D, texId);
    glEnableVertexAttribArray(VERTEX_ATTR_INDEX_V6_POSITION);
    glEnableVertexAttribArray(VERTEX_ATTR_INDEX_V6_TEXTURE);
    glVertexAttribPointer(VERTEX_ATTR_INDEX_V6_POSITION, VERTEX_VEC_COUNT_V6_PER_POSITION, GL_FLOAT,
                          GL_FALSE, STRIDE_BYTES_V6, vertexPointers);
    glVertexAttribPointer(VERTEX_ATTR_INDEX_V6_TEXTURE, VERTEX_VEC_COUNT_V6_PER_TEXTURE, GL_FLOAT,
                          GL_FALSE, STRIDE_BYTES_V6,
                          &vertexPointers[VERTEX_VEC_COUNT_V6_PER_POSITION]);
    setUniform(device.program);
    glActiveTexture(GL_TEXTURE0);
    auto vertexSize = sizeof(vertexPointers) / sizeof(GLfloat) /
                      (VERTEX_VEC_COUNT_V6_PER_POSITION + VERTEX_VEC_COUNT_V6_PER_TEXTURE);
    glDrawArrays(GL_TRIANGLE_FAN, 0, vertexSize);
    glUseProgram(GL_NONE);
    glBindTexture(GL_TEXTURE_2D, GL_NONE);
    glDisableVertexAttribArray(VERTEX_ATTR_INDEX_V6_POSITION);
    glDisableVertexAttribArray(VERTEX_ATTR_INDEX_V6_TEXTURE);

    GLfloat malletPointers[] = {
            // Order of coordinates: X, Y, R, G, B

            // Mallets
            0, -0.4, 0, 0, 1,
            0, 0.4, 1, 0, 0
    };
    glUseProgram(program);
    glEnableVertexAttribArray(0);
    glEnableVertexAttribArray(1);
    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * (2 + 3), malletPointers);
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * (2 + 3), &malletPointers[2]);
    setUniform(program);
    glDrawArrays(GL_POINTS, 0, 1);
    glDrawArrays(GL_POINTS, 1, 1);
    glUseProgram(GL_NONE);
    glDisableVertexAttribArray(0);
    glDisableVertexAttribArray(1);
}

#endif //OPENGLESPRO_GAME_STEP_6_H
